package com.wyh.controller.feemanagementcontroller;


import cn.hutool.core.date.DateTime;
import com.wyh.common.exception.CustomException;
import com.wyh.common.result.Result;
import com.wyh.domain.dto.feemanagementdto.*;
import com.wyh.domain.dto.gfive.LoginUser;
import com.wyh.domain.po.feemanagementpo.Billes;
import com.wyh.domain.po.feemanagementpo.InvoiceHeaderes;
import com.wyh.domain.po.gfive.User;
import com.wyh.security.gfive.service.TokenService;
import com.wyh.service.feemanagementservice.BillsService;
import com.wyh.service.feemanagementservice.MailService;
import com.wyh.utils.feemanagementutils.CheckCodeUtil;
import com.wyh.utils.feemanagementutils.PdfUtil;
import com.wyh.utils.feemanagementutils.SampleUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/bill")
@Slf4j
@Api(tags = "账单管理")
public class BillsController {

    @Autowired
    private BillsService billsService;

    @Autowired
    private MailService mailService;

    @Autowired
    private CheckCodeUtil checkCodeUtil;

    @Autowired
    private SampleUtil sampleUtil;

    @Autowired
    private TokenService tokenService;


    @ApiOperation(value = "周期性账单分页查询-待通知")
    @PostMapping("/pageOne")
    public Result<PageResultDTO> page(@RequestBody BillPageQueryDTO billPageQueryDTO, HttpServletRequest request) {
        log.info("账单分页查询，参数为{}", billPageQueryDTO);

         LoginUser loginUser =   tokenService.getLoginUser(request);

         User user = loginUser.getUser();

        PageResultDTO pageResult = billsService.pageQuery(billPageQueryDTO,user.getAccount());

        return Result.success(pageResult);
    }

    @ApiOperation(value = "周期性账单分页查询-已通知")
    @PostMapping("/pageTwo")
    public Result<PageResultTwoDTO> pageTwo(@RequestBody BillPageQueryDTO billPageQueryDTO,HttpServletRequest request) {
        log.info("账单分页查询，参数为{}", billPageQueryDTO);

        LoginUser loginUser =   tokenService.getLoginUser(request);

        User user = loginUser.getUser();

        PageResultTwoDTO pageResult = billsService.pageTwoQuery(billPageQueryDTO,user.getAccount());

        return Result.success(pageResult);
    }


    @ApiOperation(value = "临时账单分页查询")
    @PostMapping("/pageTp")
    public Result<PageResultTpDTO> pageTp(@RequestBody BillPageTpQueryDTO billPageTpQueryDTO,HttpServletRequest request) {
        log.info("账单分页查询，参数为{}", billPageTpQueryDTO);

        LoginUser loginUser =   tokenService.getLoginUser(request);

        User user = loginUser.getUser();

        PageResultTpDTO pageResult = billsService.pageTpQuery(billPageTpQueryDTO,user.getAccount());

        return Result.success(pageResult);
    }


    @ApiOperation(value = "账单详情查询")
    @PostMapping("/selectb")
    public Result<BillDetailCompleteDTO> getBillDetailByIdb(@RequestBody Integer id) {
        log.info("账单详情查询，参数为: {}", id);

        List<BillDetailDTO> billDetails = billsService.getBillDeatilById(id);
        List<BillDetailbDTO> billDetailsb = billsService.getBillDeatilByIdb(id);
        List<InvoiceDTO> invoice = billsService.getBillDeatilByIds(id);

        BillDetailCompleteDTO completeDTO = new BillDetailCompleteDTO();

        completeDTO.setBillDetails(billDetails != null ? billDetails : Collections.emptyList());
        completeDTO.setBillDetailsb(billDetailsb != null ? billDetailsb : Collections.emptyList());
        completeDTO.setInvoice(invoice != null ? invoice : Collections.emptyList());

        // 检查如果所有列表都为空
        if (completeDTO.getBillDetails().isEmpty() &&
                completeDTO.getBillDetailsb().isEmpty() &&
                completeDTO.getInvoice().isEmpty()) {
            return Result.error("失败", "无符合数据");
        }

        return Result.success(completeDTO);
    }



    @ApiOperation(value = "通知客户")
    @PostMapping("/sendCustomer")
    public Result sendCustomer(@RequestBody Integer[] ids) throws Exception {

        int billnotificationmethod =  billsService.getSendMethod();

        //如果billnotificationmethod为1为短信通知，2为邮件通知,3为两者都要
        if(billnotificationmethod == 1){

            String code = checkCodeUtil.generateCheckCode(6);
            String[] phones = billsService.getPhones(ids);
            sampleUtil.sendSms(phones, code);
            billsService.changeNotificationstatus(ids);
            return Result.success("短信通知成功");
        }
        else if(billnotificationmethod == 2){
            String[] emails = billsService.getEmails(ids);
            mailService.sendSimple(emails);
            billsService.changeNotificationstatus(ids);
            return Result.success("邮件通知成功-邮件列表");
        }
        else if (billnotificationmethod == 3){

            String code = checkCodeUtil.generateCheckCode(6);
            String[] phones = billsService.getPhones(ids);
            sampleUtil.sendSms(phones, code);

            String[] emails = billsService.getEmails(ids);
            mailService.sendSimple(emails);

            return Result.success("短信和邮件通知成功");
        }

        return Result.success();
    }


    @ApiOperation(value = "退回账单")
    @PostMapping("/returnBill")
    public Result returnBill(@RequestBody ReturnBillDTO returnBillDTO) {
        log.info("退回账单，参数为：", returnBillDTO);

        billsService.returnBill(returnBillDTO);

        return Result.success();
    }

//    @ApiOperation(value = "根据PDF模板导出PDF并在浏览器中打开下载界面")
//    @PostMapping("/exportPdf")
//    public void exportPdf(HttpServletResponse response, @RequestBody Integer[] ids) {
//        log.info("Received request to export PDF for IDs: {}", Arrays.toString(ids));
//
//        List<PdfDTO> pdfList = billsService.gettemplatetxt(ids);
//
//        if (pdfList == null || pdfList.isEmpty()) {
//            log.error("No PDF data found for the given ids: {}", Arrays.toString(ids));
//        }
//
//        // 定义模板路径
//        String templatePath = "templates/feemanagementtemplates/lw.pdf";
//
//        try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
//            // 设置响应头，指示浏览器下载文件
//            response.setContentType("application/zip");
//            response.setHeader("Content-Disposition", "attachment; filename=pdfs.zip");
//
//            // 生成多个PDF文件并写入ZIP输出流
//            for (int i = 0; i < pdfList.size(); i++) {
//                PdfDTO pdf = pdfList.get(i);
//                if (pdf == null) {
//                    log.warn("Skipping null PdfDTO object in list");
//                    continue;
//                }
//
//                // 创建一个新的数据映射
//                Map<String, Object> dataMap = new HashMap<>();
//                dataMap.put("name", pdf.getPayee());
//                //dataMap.put("age", pdf.getAge());  // 假设PdfDTO有getAge()方法
//                //dataMap.put("sex", pdf.getSex());  // 假设PdfDTO有getSex()方法
//
//                // 创建临时PDF文件
//                ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
//                PdfUtil.fillTemplate(dataMap, pdfOut, templatePath);
//
//                // 将生成的PDF文件添加到ZIP中
//                zipOut.putNextEntry(new ZipEntry("pdf_" + i + ".pdf"));
//                pdfOut.writeTo(zipOut);
//                zipOut.closeEntry();
//            }
//
//            log.info("PDF生成成功，已写入响应输出流");
//        } catch (IOException e) {
//            e.printStackTrace();
//
//        }
//
//    }


    @ApiOperation(value = "账单打印")
    @PostMapping("/download")
    @SneakyThrows(Exception.class)
    public Result<ReceiptDTO> download(Integer id, HttpServletResponse response, HttpServletRequest request) {
        // 防止日志记录获取session异常
        request.getSession();
        // 设置编码格式
        response.setContentType("application/pdf;charset=UTF-8");
        response.setCharacterEncoding("utf-8");

        LoginUser loginUser = tokenService.getLoginUser(request);
        User user = loginUser.getUser();

        //获取数据
        List<ExpenseDetails> expenseDetails = billsService.getExpenseDetails(id);

        //获取账单打印通知单编号
        String noticenumber =  billsService.getNoticenumber(id);

        //获取当前账单的年月
        Date timeym = billsService.getAccounttime(id);

        //获取备注
        String remarks = billsService.getRemarks();

        //获取收款相关信息
        ReceiptDTO receiptDTO = billsService.getReceipte(id,user.getAccount());

        String fileName = URLEncoder.encode("重庆中链融科技有限公司缴费账单", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");
        PdfUtil.downloadPdf(expenseDetails,noticenumber,timeym, remarks,receiptDTO,response);

        return Result.success(receiptDTO);
    }







    @ApiOperation(value = "开票")
    @PostMapping("/invoice")
    public Result<InvoiceHeaderes> invoicing(@RequestBody InvoicingDTO invoicingDTO,HttpServletRequest request){

        log.info("开票,参数为：",invoicingDTO);

        LoginUser loginUser =   tokenService.getLoginUser(request);

        User user = loginUser.getUser();

        InvoiceHeaderes invoiceHeaderes = billsService.getHeaderes(invoicingDTO.getId());

        InvoicingReDTO invoicingReDTO =  billsService.getInvoicerecords(invoicingDTO,user.getAccount());

        billsService.invoicing(invoicingReDTO);

        return Result.success(invoiceHeaderes);
    }

    @ApiOperation(value = "返回当前用户所管辖的楼盘名称列表")
    @PostMapping("/getPD")
    public Result<List<String>> getPD(HttpServletRequest request){

        LoginUser loginUser = tokenService.getLoginUser(request);
        User user = loginUser.getUser();
        List pd =  billsService.getPD(user.getAccount());

        return Result.success(pd);
    }




}
